package com.heima.article.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ArticleContentMapper;
import com.heima.article.mapper.ArticleMapper;
import com.heima.article.service.ArticleService;
import com.heima.common.constant.ArticleConstants;
import com.heima.file.FileStorageService;
import com.heima.model.article.dto.ArticleDto;
import com.heima.model.article.dto.ArticleHomeDto;
import com.heima.model.article.pojo.ApArticle;
import com.heima.model.article.pojo.ApArticleConfig;
import com.heima.model.article.pojo.ApArticleContent;
import com.heima.model.article.vo.ArticleVo;
import com.heima.model.common.dto.ResponseResult;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, ApArticle> implements ArticleService {
    @Autowired
    private ApArticleConfigMapper configMapper;
    @Autowired
    private ArticleContentMapper contentMapper;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private ArticleContentMapper articleContentMapper;
    @Autowired
    private Configuration configuration;

    @Override
    public ResponseResult loadArticleList(ArticleHomeDto dto, Short type) {
        // 数据健壮性判断
        Integer size = dto.getSize();
        if (size == null) {
            size = 10;
        }
        if (size > 50) {
            size = 50;
        }
        dto.setSize(size);

        if (type == null || (type != 1 && type != 2)) {
            type = ArticleConstants.LOADTYPE_LOAD_MORE;
        }
        String tag = dto.getTag();
        if (!StringUtils.hasLength(tag)) {
            tag = ArticleConstants.DEFAULT_TAG;
        }
        dto.setTag(tag);
        // 查询数据
        List<ArticleVo> list = getBaseMapper().findArticleListByType(dto, type);

        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult saveArticle(ArticleDto articleDto) {
        // 保存文章逻辑
        if (articleDto.getId() != null && articleDto.getId() > 0) {
            // 修改文章
            ApArticle article = new ApArticle();
            BeanUtils.copyProperties(articleDto, article);
            this.updateById(article);
            // 文章配置不允许后期修改
            // 修改内容
            ApArticleContent content = new ApArticleContent();
            content.setContent(articleDto.getContent());
            contentMapper.update(content, Wrappers.<ApArticleContent>lambdaUpdate()
                    .eq(ApArticleContent::getArticleId, articleDto.getId()));
            // 生成静态html页面
            generateHtml(article.getId());
            return ResponseResult.okResult(articleDto.getId());
        } else {
            // 新增文章
            // 文章表新增
            ApArticle article = new ApArticle();
            BeanUtils.copyProperties(articleDto, article);
            this.save(article);
            // 文章配置新增
            ApArticleConfig config = new ApArticleConfig(article.getId());
            configMapper.insert(config);
            // 文章内容新增
            ApArticleContent content = new ApArticleContent();
            content.setArticleId(article.getId());
            content.setContent(articleDto.getContent());
            contentMapper.insert(content);
            // 生成静态html页面
            generateHtml(article.getId());
            return ResponseResult.okResult(article.getId());
        }

    }


    /**
     * 根据文章id生成静态html页面，并更新url到article表中
     *
     * @param articleId
     */
    private void generateHtml(Long articleId) {
        try {
            // 根据文章id查询文章内容 id = 1302862387124125698
            ApArticleContent apArticleContent = articleContentMapper.selectOne(
                    Wrappers.
                            <ApArticleContent>lambdaQuery().
                            eq(ApArticleContent::getArticleId, articleId));
            // 把文章内容跟模板结合，生成html文件
            Template template = configuration.getTemplate("article.ftl");

            Map<String, Object> map = new HashMap<>();
            map.put("content", JSONArray.parseArray(apArticleContent.getContent()));

            // 使用StringWriter把内容输出到字符串中
            StringWriter stringWriter = new StringWriter();
            template.process(map, stringWriter);

            // 把文件传入minio
            String url = fileStorageService.uploadHtmlFile("", apArticleContent.getArticleId() + ".html", new ByteArrayInputStream(stringWriter.toString().getBytes()));
            // 把范围的url，存入数据库中
            System.out.println(url);
            ApArticle article = new ApArticle();
            article.setId(apArticleContent.getArticleId());
            article.setStaticUrl(url);
            this.updateById(article);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }
    }
}
